package bookhive.datastructures.datasource;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.TreeSet;

import org.jopac2.jbal.RecordInterface;
import org.jopac2.utils.BookSignature;
import org.jopac2.utils.JOpac2Exception;


import net.jxta.document.Element;
import net.jxta.document.StructuredDocument;

public class HashItem implements DataSourceItem, Comparable<HashItem> {

	private static final String ENCODING = "UTF-8";

	public long id;

	public String type;

	public String hash;

	public TreeSet<BookSignature> signs = null;

	public String catalogPID = null;

	public void addSignature(BookSignature bs) {
		signs.add(bs);
	}

	public HashItem() {
		id = 0;
		type = null;
		hash = null;
		signs = new TreeSet<BookSignature>();
	}

	public HashItem(RecordInterface ri) {
		id = ri.getJOpacID();
		type = ri.getTipo();
		try {
			hash = ri.getHash();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (JOpac2Exception e) {
			e.printStackTrace();
		}
		if (signs == null)
			signs = new TreeSet<BookSignature>();
		Iterator<BookSignature> bsIter = ri.getSignatures().iterator();
		while (bsIter.hasNext()) {
			signs.add(bsIter.next());
		}
	}

	public void addSignatures(Collection<BookSignature> c) {
		signs.addAll(c);
	}

	@SuppressWarnings("unchecked")
	public HashItem(Element recordEl, String cPID) {

		catalogPID = cPID;

		signs = new TreeSet<BookSignature>();
		Enumeration recordAttrs = recordEl.getChildren();
		while (recordAttrs.hasMoreElements()) {
			Element attr = (Element) recordAttrs.nextElement();
			Object value = attr.getValue();
			if (attr.getKey().toString().equals("Id") && value != null) {
				id = Long.parseLong(attr.getValue().toString());
			} else if (attr.getKey().toString().equals("Type") && value != null) {
				type = attr.getValue().toString();
				try {
					type = URLDecoder.decode(type, ENCODING);
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			} else if (attr.getKey().toString().equals("Hash") && value != null) {
				hash = attr.getValue().toString();
				try {
					hash = URLDecoder.decode(hash, ENCODING);
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			} else if (attr.getKey().toString().equals("Signatures")) {

				Enumeration signIter = attr.getChildren("Signature");
				while (signIter.hasMoreElements()) {
					String lid = null, lname = null, booknum = null, bookloc = null, cons = null;
					Enumeration signAttrs = ((Element) signIter.nextElement())
							.getChildren();
					while (signAttrs.hasMoreElements()) {
						Element signAttr = (Element) signAttrs.nextElement();
						Object value1 = signAttr.getValue();
						if (value1 == null)
							continue;
						if (signAttr.getKey().toString().equals("LibraryId")) {
							lid = value1.toString();
							try {
								lid = URLDecoder.decode(lid, ENCODING);
							} catch (UnsupportedEncodingException e) {
								e.printStackTrace();
							}
						} else if (signAttr.getKey().toString().equals(
								"LibraryName")) {
							lname = value1.toString();
							try {
								lname = URLDecoder.decode(lname, ENCODING);
							} catch (UnsupportedEncodingException e) {
								e.printStackTrace();
							}
						} else if (signAttr.getKey().toString().equals(
								"IdNumber")) {
							booknum = value1.toString();
							try {
								booknum = URLDecoder.decode(booknum, ENCODING);
							} catch (UnsupportedEncodingException e) {
								e.printStackTrace();
							}
						} else if (signAttr.getKey().toString().equals(
								"Localization")) {
							bookloc = value1.toString();
							try {
								bookloc = URLDecoder.decode(bookloc, ENCODING);
							} catch (UnsupportedEncodingException e) {
								e.printStackTrace();
							}
						} else if (signAttr.getKey().toString().equals("Cons")) {
							cons = value1.toString();
							try {
								cons = URLDecoder.decode(cons, ENCODING);
							} catch (UnsupportedEncodingException e) {
								e.printStackTrace();
							}
						}
					}
					BookSignature sign = new BookSignature(lid, lname, booknum,
							bookloc, cons);
					signs.add(sign);
				}
			}
		}
	}

	@SuppressWarnings("unchecked")
	public HashItem(Element recordEl) {
		new HashItem(recordEl, "");
	}

	@SuppressWarnings("unchecked")
	public void addToParentElement(Element parent, StructuredDocument response)
			throws UnsupportedEncodingException {
		Element recordEl = response.createElement("Record");
		parent.appendChild(recordEl);

		Element attrEl = response.createElement("Id", URLEncoder.encode(String
				.valueOf(id), ENCODING));
		recordEl.appendChild(attrEl);

		if (type != null && type.length() > 0) {
			attrEl = response.createElement("Type", URLEncoder.encode(type,
					ENCODING));
			recordEl.appendChild(attrEl);
		}

		attrEl = response.createElement("Hash", URLEncoder.encode(hash,
				ENCODING));
		recordEl.appendChild(attrEl);
		Element signsEl = response.createElement("Signatures");
		recordEl.appendChild(signsEl);

		if (signs == null)
			return;

		Iterator<BookSignature> signsIter = signs.iterator();
		while (signsIter.hasNext()) {
			BookSignature sign = signsIter.next();
			Element signEl = response.createElement("Signature");
			signsEl.appendChild(signEl);

			String lid = URLEncoder.encode(sign.getLibraryId(), ENCODING);
			String lname = URLEncoder.encode(sign.getLibraryName(), ENCODING);
			String bnum = URLEncoder.encode(sign.getBookNumber(), ENCODING);
			String bloc = URLEncoder.encode(sign.getBookLocalization(),
					ENCODING);
			String cons = URLEncoder.encode(sign.getBookCons(), ENCODING);
			if (lid.length() > 0) {
				attrEl = response.createElement("LibraryId", lid);
				signEl.appendChild(attrEl);
			}
			if (lname.length() > 0) {
				attrEl = response.createElement("LibraryName", lname);
				signEl.appendChild(attrEl);
			}
			if (bnum.length() > 0) {
				attrEl = response.createElement("IdNumber", bnum);
				signEl.appendChild(attrEl);
			}
			if (bloc.length() > 0) {
				attrEl = response.createElement("Localization", bloc);
				signEl.appendChild(attrEl);
			}
			if (cons.length() > 0) {
				attrEl = response.createElement("Cons", cons);
				signEl.appendChild(attrEl);
			}
		}

	}

	@Override
	public String toString() {
		StringBuffer ret = new StringBuffer();
		ret.append("Hash: " + hash + "\nId: " + id + "\nType: " + type
				+ "\nSignatures:\n");
		Iterator<BookSignature> i = signs.iterator();
		while (i.hasNext()) {
			BookSignature bs = i.next();
			ret.append("Signature: " + bs.getLibraryId() + " - "
					+ bs.getLibraryName() + " - " + bs.getBookNumber() + " - "
					+ bs.getBookLocalization() + " - " + bs.getBookCons()
					+ "\n");
		}
		return ret.toString();
	}

	public int compareTo(HashItem di2) {

		return hash.compareTo(((HashItem) di2).hash);

	}

	public String getHash() {
		return this.hash;
	}

}
